<?php

namespace App\Service\Renew;

use App\Enums\OpenShop\InvestmentPromotion\ContractStatusEnum;
use App\Enums\OpenShop\InvestmentPromotion\UserContractEnum;
use App\Enums\Workflow\WorkflowEnum;
use App\Error\OpenShop\RenewError;
use App\Exceptions\KfHttpResponseException;
use App\Http\Resources\OpenShop\ExpireShop\FrontExpireShopListResource;
use App\Models\BaseModel;
use App\Models\Kms\User\KmsUser;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserContractModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserIdentityCardModel;
use App\Models\OpenShop\Shop\OpenShopHandleExpireShopHistoryModel;
use App\Models\OpenShop\Shop\OpenShopHandleExpireShopMainModel;
use App\Models\OpenShop\ShopCheckAccept\OpenShopCheckAcceptModel;
use App\Models\Renew\RenewOrder\RenewDeferOperateHistoryModel;
use App\Models\Workflow\WorkflowOrderModel;
use App\Models\Workflow\WorkflowOrderNodeModel;
use App\Remote\Feishu\FeishuMsgRemote;
use App\Remote\Rms\RmsShopRemote;
use App\Service\Common\CommonPermissionService;
use App\Service\Cruise\Mission\RenewInputService;
use App\Service\OpenShop\Feishu\BaseService;
use App\Service\OpenShop\Feishu\UserExtContractService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Kuafu\Nsq\NsqPublisher;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class RenewOrderService extends BaseService
{

    /**
     * @param int $shopCode 门店code
     * @param int $rmsUserId rms.userId
     * @param string $workNo 工单号
     * @param string $headerTitle 消息标题
     * @param string $jumpLink 消息点击跳转地址
     * @param string $handleRole 处理人角色
     * @param string $handleDate 处理时间
     * @throws GuzzleException
     */
    public static function flowNodeFsMsgSend(
        int $shopCode,
        int $rmsUserId,
        string $workNo,
        string $headerTitle,
        string $jumpLink,
        string $handleRole,
        string $handleDate
    ) {
        try {
            $fsUserDetail = KmsUser::query()->where("rmsUserId", $rmsUserId)->first();
            if (!$fsUserDetail) {
                Log::warning("flowNodeFsMsgSend empty rmsUserId: {$rmsUserId}");
                return;
            }

            $msgTemplateContents = view()->file(
                app_path("Remote/Feishu/FsTemplate/Renew") . "/RenewFlowNodeMsgTemplate.blade.php",
                [
                    "headerTitle" => $headerTitle,
                    "workNo"      => $workNo,
                    "jumpLink"    => $jumpLink,
                    "handleRole"  => $handleRole,
                    "userOpenId"  => $fsUserDetail->openId,
                    "handleDate"  => $handleDate,
                    "shopCode"    => $shopCode
                ]
            )->render();

            FeishuMsgRemote::getInstance()->sendInteractiveMsg(
                $msgTemplateContents,
                $fsUserDetail->userId
            );
        } catch (Exception $exception) {
            logException("续签单据节点消息推送出错", $exception, func_get_args(), true, true);
        }
    }

    /**
     * 延期有效期
     *
     * @param object $params
     * @throws Exception
     */
    public static function renewDeferOrder(object $params)
    {
        try {
            //获取当前订单信息
            $userContractModel = OpenShopUserContractModel::getUserContractDetail($params->orderNo);
//            $renewMain         = OpenShopMainProcessModel::getRenewOrderMainByParentId($userContractModel->mainProcessRel->id);
            //判断续签单信息
//            $renewMainOrderNo = attributeGet($renewMain, "orderNo", "");
//            if ($renewMainOrderNo) {
//                $renewUserContractModel = OpenShopUserContractModel::getUserContractDetail($renewMain->order);
//                if ($renewUserContractModel->detailStatus == ContractStatusEnum::COMPLETE) {
//                    throw new KfHttpResponseException(RenewError::EXISTS_RENEW_SIGN_ORDER);
//                }
//            }
            //最后一条延期记录
            $lastDeferModel = RenewDeferOperateHistoryModel::getLastDeferHistoryByShopCode($userContractModel->signOrderRel->shopCode);
            $lastEndTime    = attributeGet($lastDeferModel, "endTime", 0);
            if ($userContractModel->endTime > $lastEndTime) {
                $lastEndTime = $userContractModel->endTime;
            }
            if (strtotime($params->date) <= $userContractModel->endTime) {
                throw new KfHttpResponseException(RenewError::CONTRACT_END_TIME_GT_DEFER_TIME);
            }
            RenewDeferOperateHistoryModel::query()->insert([
                "shopId"       => $userContractModel->mainProcessRel->shopId,
                "shopCode"     => $userContractModel->signOrderRel->shopCode,
                "orderNo"      => $params->orderNo,
                "lastEndTime"  => $lastEndTime,
                "endTime"      => strtotime("+1 day", strtotime($params->date)),
                "createdAt"    => time(),
                "createdByUid" => request()->user()->id
            ]);

            (new NsqPublisher(config('nsq.default.address')))
                ->pub('tiger.openShop.shopStatus.switch', [
                    'nsqEventTime'  => time(),
                    'shopId'        => $userContractModel->mainProcessRel->shopId,
                    'switch'        => 1, // 门店禁用关闭为 0
                    'operatorId'    => 0,
                    'operatorName'  => request()->user()->username,
                    'reason'        => "续签订货延期至【 {$params->date} 】",
                    'operationTime' => time()
                ]);

            // 自动停收银
            RmsShopRemote::updateShopFieldById(
                $userContractModel->mainProcessRel->shopId,
                ['cashRegisterStatus' => RmsShopRemote::SHOP_CASH_REGISTER_STATUS_OK]
            );


        } catch (Exception $exception) {
            handleKfException($exception);
        }
    }


    /**
     * 生成续签合同
     *
     * @param string $orderNo
     * @param string $workflowNo
     * @param string $contractStartTime
     * @param string $contractEndTime
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     */
    public static function generateRenewUserContract(
        string $orderNo,
        string $workflowNo,
        string $contractStartTime = "",
        string $contractEndTime = ""
    ) {
        try {
            OpenShopUserContractModel::query()
                                     ->where("orderNo", $orderNo)
                                     ->where("workflowNo", $workflowNo)
                                     ->update(["isDeleted" => 1]);

            $userContractCount = OpenShopUserContractModel::query()
                                                          ->where("orderNo", $orderNo)->count();
            if ($userContractCount == 1) {
                $originalUserContract = OpenShopUserContractModel::query()
                                                                 ->where("orderNo", $orderNo)->first();
            } else {
                $originalUserContract = OpenShopUserContractModel::query()
                                                                 ->where("orderNo", $orderNo)
                                                                 ->whereIn("contractType",
                                                                     OpenShopUserContractModel::OPEN_SHOP_CONTRACT_GROUP)
                                                                 ->where("detailStatus", ContractStatusEnum::COMPLETE)
                                                                 ->orderBy("id", "desc")
                                                                 ->first();
            }

            if (empty($originalUserContract)) {
                throw new Exception("原始合同查找失败，请核实后再发起操作");
            }

            if ($contractStartTime) {
                $startTime = strtotime($contractStartTime);
            } else {
                $startTime = strtotime("+1 day", $originalUserContract->endTime);
            }

            if ($contractEndTime) {
                $endTime = strtotime($contractEndTime);
            } else {
                $endTime = $originalUserContract->endTime < time() ?
                    strtotime("-1 day", strtotime("+1 year", time()))
                    :
                    strtotime("+1 year", $originalUserContract->endTime);
            }
            //构建合同信息
            $userContractId = OpenShopUserContractModel::query()->insertGetId(
                array_merge(collect($originalUserContract->toArray())->except(["id"])->toArray(), [
                    "contractExtNo"  => "",
                    "categoryName"   => "",
                    "categoryId"     => "",
                    "exceptionMsg"   => "",
                    "invalidedUid"   => "",
                    "detailStatus"   => "",
                    "contractStatus" => 0,
                    "contractType"   => UserContractEnum::CONTRACT_TYPE_8,
                    "signTime"       => 0,
                    "workflowNo"     => $workflowNo,
                    "createdAt"      => time(),
                    "startTime"      => $startTime,
                    "endTime"        => $endTime
                ])
            );

            $bizId                    = vsprintf("%s-%s", [$orderNo, $userContractId]);
            $signOrder                = OpenShopSignOrderModel::getOrderDetailByOrderNo($orderNo);
            $generateContractResponse = UserExtContractService::commonGenerateContract(
                $bizId,
                "合同续签",
                "{$orderNo} 续签",
                UserContractEnum::CONTRACT_TYPE_8_KEY,
                UserExtContractService::commonBuildBuildSignatory(UserContractEnum::CONTRACT_TYPE_8_KEY, $signOrder),
                UserExtContractService::commonBuildTemplateParams(UserContractEnum::CONTRACT_TYPE_8_KEY, $signOrder,
                    []),
                $orderNo
            );

            \App\Service\Common\UserContractService::handleGenerateRenewContract(
                $bizId,
                $generateContractResponse
            );
        } catch (Exception $exception) {
            handleException($exception, null, func_get_args(), "契约锁合同生成失败");
        }
    }


    /**
     * 构建续签提醒基础权限查询条件
     *
     * @return Builder|mixed
     */
    public static function getRenewWorkOrderBaseQuery()
    {
        // 不同路由获取
        $action     = request()->route()->getAction();
        $middleware = attributeGet($action, "middleware", []);
        $hasAllPermission = true;
        if (!in_array('kmsAuth:kmsApi', $middleware)) {
            $hasAllPermission = CommonPermissionService::hasAllPermission("b.openShop.feishu.renewWorkOrder.index");
        }
        return OpenShopHandleExpireShopMainModel::query()->when(!$hasAllPermission, function ($query) {
            list($isHeadOffice, $provinceCodeLists) = CommonPermissionService::getOrganizationRegion(request()->user()->id);
            if ($isHeadOffice) {
                return $query;
            }
            //省总门店
            $provinceOrderNoGroup = OpenShopAddressModel::query()->whereIn('provinceCode', $provinceCodeLists)
                                                        ->pluck('orderNo')->toArray();
            //督导门店
            $managerOrderNoGroup = OpenShopCheckAcceptModel::query()->where("managerId", request()->user()->id)
                                                           ->pluck('orderNo')->toArray();
            $signOrders          = array_unique(array_merge($provinceOrderNoGroup, $managerOrderNoGroup));
            if ($signOrders) {
                $query->whereIn("orderNo", $signOrders);
            } else {
                $query->where("id", 0);
            }
        });
    }

    /**
     * @return array|void
     * @throws ValidationException
     */
    public static function pendingRenewOrderMsg()
    {
        try {
            $baseQuery           = self::getRenewWorkOrderBaseQuery();
            $todayBeginTimestamp = strtotime(formatDateYmd(time()));
            $count               = $baseQuery->whereRaw("workOrderNo not in (" . BaseModel::toSqlWithParam(WorkflowOrderModel::query()
                                                                                                                             ->where('status',
                                                                                                                                 WorkflowOrderModel::STATUS_FINISH)
                                                                                                                             ->select(["workflowNo"])) . ')')
                                             ->where("contractEndTime", "<", strtotime("+30 day", $todayBeginTimestamp))
                                             ->where("contractEndTime", ">", time())
                                             ->count();

            return [
                "msgContents" => sprintf("目前有%d家续签门店即将过期 (近一个月内)，请重点关注!", $count)
            ];
        } catch (Exception $exception) {
            handleException($exception, null, func_get_args(), "获取续签待办消息失败");
        }
    }


    /**
     * @return array
     */
    public static function renewWorkOrderGroup(): array
    {
        $baseQuery = self::getRenewWorkOrderBaseQuery();
        //剔除已完成工单
        $baseQuery           = $baseQuery->whereRaw(
            "workOrderNo not in (" . BaseModel::toSqlWithParam(WorkflowOrderModel::query()->where('status',
                WorkflowOrderModel::STATUS_FINISH)->select(["workflowNo"])) . ')'
        );
        $todayBeginTimestamp = strtotime(formatDateYmd(time()));
        return [
            "group" => collect(OpenShopHandleExpireShopHistoryModel::TYPE_TEXT_GROUP)->map(function ($text, $type) use (
                $baseQuery,
                $todayBeginTimestamp
            ) {
                $count = 0;
                switch ($type) {
                    case OpenShopHandleExpireShopHistoryModel::TYPE_0://全部
                        $count = (clone $baseQuery)->count();
                        break;
                    case OpenShopHandleExpireShopHistoryModel::TYPE_1://近90天
                        $count = (clone $baseQuery)
                            ->where("contractEndTime", "<", strtotime("+90 day", $todayBeginTimestamp))
                            ->where("contractEndTime", ">", time())
                            ->count();
                        break;
                    case OpenShopHandleExpireShopHistoryModel::TYPE_2://近60天
                        $count = (clone $baseQuery)
                            ->where("contractEndTime", "<", strtotime("+60 day", $todayBeginTimestamp))
                            ->where("contractEndTime", ">", time())
                            ->count();
                        break;
                    case OpenShopHandleExpireShopHistoryModel::TYPE_3://近30天
                        $count = (clone $baseQuery)
                            ->where("contractEndTime", "<", strtotime("+30 day", $todayBeginTimestamp))
                            ->where("contractEndTime", ">", time())
                            ->count();
                        break;
                    case OpenShopHandleExpireShopHistoryModel::TYPE_4://当天到期
                        $count = (clone $baseQuery)
                            ->where("contractEndTime", "<", strtotime("+1 day", $todayBeginTimestamp))
                            ->where("contractEndTime", ">", time())
                            ->count();
                        break;
                    case OpenShopHandleExpireShopHistoryModel::TYPE_5://已过期
                        $count = (clone $baseQuery)
                            ->where("contractEndTime", "<", time())
                            ->count();
                        break;
                }
                return [
                    "type"  => $type,
                    "count" => $count,
                    "text"  => $text
                ];
            })->values()->toArray()
        ];
    }


    /**
     * 续签工单列表
     *
     * @param object $params
     * @return array|void
     * @throws ValidationException
     */
    public static function renewWorkOrderGroupList(object $params)
    {
        try {
            $search              = attributeGet($params, "search", "");
            $todayBeginTimestamp = strtotime(formatDateYmd(time()));
            $baseQuery           = self::getRenewWorkOrderBaseQuery();
            //剔除已完成工单
            $baseQuery = $baseQuery->whereRaw(
                "workOrderNo not in (" . BaseModel::toSqlWithParam(WorkflowOrderModel::query()->where('status',
                    WorkflowOrderModel::STATUS_FINISH)->select(["workflowNo"])) . ')'
            );
            $paginate  = $baseQuery->with([
                "workflowOrderRel",
                "mainProcessRel" => function ($query) {
                    $query->with([
                        "userIdentityCardRel"
                    ]);
                }
            ])->when(
                in_array($params->type, array_keys(OpenShopHandleExpireShopHistoryModel::TYPE_TEXT_GROUP)),
                function ($query) use ($params, $todayBeginTimestamp) {
                    switch ($params->type) {
                        case OpenShopHandleExpireShopHistoryModel::TYPE_1://近90天
                            $query->where("contractEndTime", "<", strtotime("+90 day", $todayBeginTimestamp))
                                  ->where("contractEndTime", ">", time())
                                  ->count();
                            break;
                        case OpenShopHandleExpireShopHistoryModel::TYPE_2://近60天
                            $query->where("contractEndTime", "<", strtotime("+60 day", $todayBeginTimestamp))
                                  ->where("contractEndTime", ">", time())
                                  ->count();
                            break;
                        case OpenShopHandleExpireShopHistoryModel::TYPE_3://近30天
                            $query->where("contractEndTime", "<", strtotime("+30 day", $todayBeginTimestamp))
                                  ->where("contractEndTime", ">", time())
                                  ->count();
                            break;
                        case OpenShopHandleExpireShopHistoryModel::TYPE_4://当天到期
                            $query->where("contractEndTime", "<", strtotime("+1 day", $todayBeginTimestamp))
                                  ->where("contractEndTime", ">", time())
                                  ->count();
                            break;
                        case OpenShopHandleExpireShopHistoryModel::TYPE_5://已过期
                            $query->where("contractEndTime", "<", time())
                                  ->count();
                            break;
                    }
                }
            )->when(strlen($search), function ($query) use ($search) {
                if (is_numeric($search)) {
                    $query->where("shopCode", "like", "%{$search}%");
                } else {
                    $shopCodes = [];
                    OpenShopUserIdentityCardModel::query()->with([
                        "mainProcessRel" => function ($query) {
                            $query->with("signOrderRel");
                        }
                    ])->where(
                        "name", "like", "%{$search}%"
                    )->get()->map(function (OpenShopUserIdentityCardModel $identityCardModel) use (&$shopCodes) {
                        $identityCardModel->mainProcessRel->each(function (OpenShopMainProcessModel $mainProcessModel
                        ) use (&$shopCodes) {
                            $shopCode = attributeGet($mainProcessModel, "signOrderRel.shopCode", 0);
                            if ($shopCode > 0) {
                                array_push($shopCodes, $shopCode);
                            }
                        });
                    });

                    if ($shopCodes) {
                        $query->whereIn("shopCode", $shopCodes);
                    } else {
                        $query->where("id", 0);
                    }
                }
            })->paginate($params->pageSize, ['*'], 'pageNum', $params->pageNum);

            if ($paginate->items()) {
                $shopCodes                   = collect($paginate->items())->pluck("shopCode")->toArray();
                request()->rmsShopCollection = collect(RmsShopRemote::getShopInfosByCodes($shopCodes)["shopList"]);
            }

            return [
                "timestamp" => time(),
                "list"      => FrontExpireShopListResource::collection($paginate->items()),
                "pageSize"  => (int)$params->pageSize,
                "pageNum"   => (int)$params->pageNum,
                "total"     => (int)$paginate->total()
            ];

        } catch (Exception $exception) {
            handleException($exception, null, func_get_args(), "获取续签提醒列表失败");
        }
    }


    /**
     * 续签流程 - 工作台顶部统计聚合数据
     *
     * @return array
     */
    public static function renewWorkOrderFlowGroup(): array
    {
        $baseQuery = self::getRenewWorkOrderBaseQuery();

        $workflowOrderIdsBuilders = WorkflowOrderModel::query()
                                                      ->whereRaw("workflowNo in (" . BaseModel::toSqlWithParam($baseQuery->select(["workOrderNo"])) . ')')
                                                      ->where('status', WorkflowOrderModel::STATUS_ING);

        return [
            "group" => collect(OpenShopHandleExpireShopMainModel::FLOW_NODE_TEXT)->map(function ($text, $type) use (
                $workflowOrderIdsBuilders,
                $baseQuery
            ) {
                $count = 0;
                switch ($type) {
                    case OpenShopHandleExpireShopMainModel::FLOW_NODE_1:
                        $count = WorkflowOrderNodeModel::query()
                                                       ->whereRaw("workflowOrderId in (" . BaseModel::toSqlWithParam($workflowOrderIdsBuilders->select("id")) . ')')
                                                       ->where('status', WorkflowOrderNodeModel::STATUS_ING)
                                                       ->where('businessType', WorkflowEnum::BUSINESS_TYPE_SUBMIT_APPLY)
                                                       ->count();
                        break;
                    case OpenShopHandleExpireShopMainModel::FLOW_NODE_2:
                        // 待初审
                        $count = WorkflowOrderNodeModel::query()
                                                       ->whereRaw("workflowOrderId in (" . BaseModel::toSqlWithParam($workflowOrderIdsBuilders->select("id")) . ')')
                                                       ->where('status', WorkflowOrderNodeModel::STATUS_ING)
                                                       ->where('businessType', WorkflowEnum::BUSINESS_TYPE_FIX_AUDIT)
                                                       ->whereIn('handlerType',
                                                           [
                                                               WorkflowEnum::HANDLER_TYPE_SUPERVISE,
                                                               WorkflowEnum::HANDLER_TYPE_PROVINCE
                                                           ])
                                                       ->count();
                        break;
                    case OpenShopHandleExpireShopMainModel::FLOW_NODE_3:
                        // 待复审
                        $count = WorkflowOrderNodeModel::query()
                                                       ->whereRaw("workflowOrderId in (" . BaseModel::toSqlWithParam($workflowOrderIdsBuilders->select("id")) . ')')
                                                       ->where('status', WorkflowOrderNodeModel::STATUS_ING)
                                                       ->where('businessType', WorkflowEnum::BUSINESS_TYPE_FIX_AUDIT)
                                                       ->whereIn('handlerType',
                                                           [
                                                               WorkflowEnum::HANDLER_TYPE_HEAD
                                                           ])
                                                       ->count();

                        break;
                    case OpenShopHandleExpireShopMainModel::FLOW_NODE_4:
                        // 待签署
                        $count = WorkflowOrderNodeModel::query()
                                                       ->whereRaw("workflowOrderId in (" . BaseModel::toSqlWithParam($workflowOrderIdsBuilders->select("id")) . ')')
                                                       ->where('status', WorkflowOrderNodeModel::STATUS_ING)
                                                       ->where('businessType', WorkflowEnum::BUSINESS_TYPE_RENEW_SIGN)
                                                       ->count();
                        break;
                    case OpenShopHandleExpireShopMainModel::FLOW_NODE_5:
                        // 已完成 - order主表
                        $count = WorkflowOrderModel::query()
                                                   ->whereRaw("workflowNo in (" . BaseModel::toSqlWithParam($baseQuery->select(["workOrderNo"])) . ')')
                                                   ->where('status', WorkflowOrderModel::STATUS_FINISH)
                                                   ->count();
                        break;
                }
                return [
                    "type"  => $type,
                    "count" => $count,
                    "text"  => $text
                ];
            })->values()->toArray()
        ];
    }

    /**
     * 续签工单列表
     *
     * @param object $params
     * @return array|void
     * @throws ValidationException
     */
    public static function renewWorkOrderFlowGroupList(object $params)
    {
        try {
            $search   = attributeGet($params, "search", "");
            $paginate = self::getRenewWorkOrderBaseQuery()->with([
                "workflowOrderRel",
                "mainProcessRel" => function ($query) {
                    $query->with([
                        "userIdentityCardRel"
                    ]);
                }
            ])->when(
                in_array($params->type, array_keys(OpenShopHandleExpireShopMainModel::FLOW_NODE_TEXT)),
                function ($query) use ($params) {
                    $subQueryBuilder = WorkflowOrderModel::query();
                    switch ($params->type) {
                        case OpenShopHandleExpireShopMainModel::FLOW_NODE_1:
                            $workflowOrderNodeQuery = WorkflowOrderNodeModel::query()
                                                                            ->where('status',
                                                                                WorkflowOrderNodeModel::STATUS_ING)
                                                                            ->where('businessType',
                                                                                WorkflowEnum::BUSINESS_TYPE_SUBMIT_APPLY);
                            $subQueryBuilder->whereRaw("id in (" . BaseModel::toSqlWithParam($workflowOrderNodeQuery->select("workflowOrderId")) . ")");
                            break;
                        case OpenShopHandleExpireShopMainModel::FLOW_NODE_2:
                            $workflowOrderNodeQuery = WorkflowOrderNodeModel::query()
                                                                            ->where('status',
                                                                                WorkflowOrderNodeModel::STATUS_ING)
                                                                            ->where('businessType',
                                                                                WorkflowEnum::BUSINESS_TYPE_FIX_AUDIT)
                                                                            ->whereIn('handlerType',
                                                                                [
                                                                                    WorkflowEnum::HANDLER_TYPE_SUPERVISE,
                                                                                    WorkflowEnum::HANDLER_TYPE_PROVINCE
                                                                                ]);
                            $subQueryBuilder->whereRaw("id in (" . BaseModel::toSqlWithParam($workflowOrderNodeQuery->select("workflowOrderId")) . ")");
                            break;
                        case OpenShopHandleExpireShopMainModel::FLOW_NODE_3:
                            $workflowOrderNodeQuery = WorkflowOrderNodeModel::query()
                                                                            ->where('status',
                                                                                WorkflowOrderNodeModel::STATUS_ING)
                                                                            ->where('businessType',
                                                                                WorkflowEnum::BUSINESS_TYPE_FIX_AUDIT)
                                                                            ->whereIn('handlerType',
                                                                                [
                                                                                    WorkflowEnum::HANDLER_TYPE_HEAD
                                                                                ]);
                            $subQueryBuilder->whereRaw("id in (" . BaseModel::toSqlWithParam($workflowOrderNodeQuery->select("workflowOrderId")) . ")");
                            break;
                        case OpenShopHandleExpireShopMainModel::FLOW_NODE_4:
                            $workflowOrderNodeQuery = WorkflowOrderNodeModel::query()
                                                                            ->where('status',
                                                                                WorkflowOrderNodeModel::STATUS_ING)
                                                                            ->where('businessType',
                                                                                WorkflowEnum::BUSINESS_TYPE_RENEW_SIGN);
                            $subQueryBuilder->whereRaw("id in (" . BaseModel::toSqlWithParam($workflowOrderNodeQuery->select("workflowOrderId")) . ")");
                            break;
                        case OpenShopHandleExpireShopMainModel::FLOW_NODE_5:
                            $subQueryBuilder->where('status', WorkflowOrderModel::STATUS_FINISH);
                            break;
                    }
                    $query->whereRaw("workOrderNo in (" . BaseModel::toSqlWithParam($subQueryBuilder->select("workflowNo")) . ")");
                }
            )->when(strlen($search), function ($query) use ($search) {
                if (is_numeric($search)) {
                    $query->where("shopCode", "like", "%{$search}%");
                } else {
                    $shopCodes = [];
                    OpenShopUserIdentityCardModel::query()->with([
                        "mainProcessRel" => function ($query) {
                            $query->with("signOrderRel");
                        }
                    ])->where(
                        "name", "like", "%{$search}%"
                    )->get()->map(function (OpenShopUserIdentityCardModel $identityCardModel) use (&$shopCodes) {
                        $identityCardModel->mainProcessRel->each(function (OpenShopMainProcessModel $mainProcessModel
                        ) use (&$shopCodes) {
                            $shopCode = attributeGet($mainProcessModel, "signOrderRel.shopCode", 0);
                            if ($shopCode > 0) {
                                array_push($shopCodes, $shopCode);
                            }
                        });
                    });

                    if ($shopCodes) {
                        $query->whereIn("shopCode", $shopCodes);
                    } else {
                        $query->where("id", 0);
                    }
                }
            })->paginate($params->pageSize, ['*'], 'pageNum', $params->pageNum);

            if ($paginate->items()) {
                $shopCodes                   = collect($paginate->items())->pluck("shopCode")->toArray();
                request()->rmsShopCollection = collect(RmsShopRemote::getShopInfosByCodes($shopCodes)["shopList"]);
            }

            return [
                "timestamp" => time(),
                "list"      => FrontExpireShopListResource::collection($paginate->items()),
                "pageSize"  => (int)$params->pageSize,
                "pageNum"   => (int)$params->pageNum,
                "total"     => (int)$paginate->total()
            ];

        } catch (Exception $exception) {
            handleException($exception, null, func_get_args(), "获取续签流程列表失败");
        }
    }

    /**
     * 续签工单列表
     *
     * @param object $params
     * @return array|void
     * @throws ValidationException
     */
    public static function renewWorkOrderList(object $params)
    {
        try {
            $search   = attributeGet($params, "search", "");
            $paginate = self::getRenewWorkOrderBaseQuery()->with([
                "workflowOrderRel",
                "mainProcessRel" => function ($query) {
                    $query->with([
                        "userIdentityCardRel"
                    ]);
                }
            ])->when(strlen($search), function ($query) use ($search) {
                if (is_numeric($search)) {
                    $query->where("shopCode", "like", "%{$search}%");
                } else {
                    $shopCodes = [];
                    OpenShopUserIdentityCardModel::query()->with([
                        "mainProcessRel" => function ($query) {
                            $query->with("signOrderRel");
                        }
                    ])->where(
                        "name", "like", "%{$search}%"
                    )->get()->map(function (OpenShopUserIdentityCardModel $identityCardModel) use (&$shopCodes) {
                        $identityCardModel->mainProcessRel->each(function (OpenShopMainProcessModel $mainProcessModel
                        ) use (&$shopCodes) {
                            $shopCode = attributeGet($mainProcessModel, "signOrderRel.shopCode", 0);
                            if ($shopCode > 0) {
                                array_push($shopCodes, $shopCode);
                            }
                        });
                    });

                    if ($shopCodes) {
                        $query->whereIn("shopCode", $shopCodes);
                    } else {
                        $query->where("id", 0);
                    }
                }
            })->paginate($params->pageSize, ['*'], 'pageNum', $params->pageNum);

            if ($paginate->items()) {
                $shopCodes                   = collect($paginate->items())->pluck("shopCode")->toArray();
                request()->rmsShopCollection = collect(RmsShopRemote::getShopInfosByCodes($shopCodes)["shopList"]);
            }

            return [
                "timestamp" => time(),
                "list"      => FrontExpireShopListResource::collection($paginate->items()),
                "pageSize"  => (int)$params->pageSize,
                "pageNum"   => (int)$params->pageNum,
                "total"     => (int)$paginate->total()
            ];

        } catch (Exception $exception) {
            handleException($exception, null, func_get_args(), "获取续签列表失败");
        }
    }

    /**
     * @param array $shopIds
     * @return array
     */
    public static function getRenewOrdersByShopIds(array $shopIds): array
    {
        $expireShopMainModel = OpenShopHandleExpireShopMainModel::query()->whereIn("shopId", $shopIds)
                                                                ->whereRaw("workOrderNo not in (" . BaseModel::toSqlWithParam(WorkflowOrderModel::query()
                                                                                                                                                ->whereIn("shopId",
                                                                                                                                                    $shopIds)
                                                                                                                                                ->where('status',
                                                                                                                                                    WorkflowOrderModel::STATUS_FINISH)
                                                                                                                                                ->select(["workflowNo"])) . ')')
                                                                ->select(["shopId", "workOrderNo"])->get()
                                                                ->map(function (
                                                                    OpenShopHandleExpireShopMainModel $shopHandleExpireShopMainModel
                                                                ) {
                                                                    $shopHandleExpireShopMainModel->linkUrl = vsprintf("%s%s%s",
                                                                        [
                                                                            config('webUrl.notify_web_cdn_url'),
                                                                            "#/pages/work-order/renewal/renewal?workflowNo=",
                                                                            $shopHandleExpireShopMainModel->workOrderNo
                                                                        ]);
                                                                    return $shopHandleExpireShopMainModel;
                                                                });
        return $expireShopMainModel->toArray();
    }


    /**
     * 续签合同签约完成业务处理
     *
     * @param OpenShopUserContractModel $userContractModel
     * @throws GuzzleException
     */
    public static function finishRenewFlowOrder(OpenShopUserContractModel $userContractModel)
    {
        try {
            ## 签约完成
            (new RenewInputService(0, 0))
                ->setWorkflowOrderNo($userContractModel->workflowNo)
                ->finish();

            //todo  开启收银 & 订货
            (new NsqPublisher(config('nsq.default.address')))
                ->pub('tiger.openShop.shopStatus.switch', [
                    'nsqEventTime'  => time(),
                    'shopId'        => $userContractModel->mainProcessRel->shopId,
                    'switch'        => 1, // 门店禁用关闭为 0
                    'operatorId'    => 0,
                    'operatorName'  => "续签合同签约回调",
                    'reason'        => "续签合同签约完成回调开启订货",
                    'operationTime' => time()
                ]);

            RmsShopRemote::updateShopFieldById(
                $userContractModel->mainProcessRel->shopId,
                ['cashRegisterStatus' => RmsShopRemote::SHOP_CASH_REGISTER_STATUS_OK]
            );
        } catch (Exception $exception) {
            logException("续签单签约回调更新工单状态报错", $exception, $userContractModel->toArray(), true, true);
        }
    }
}
